#include "Automat.h"
#include <iostream>
#include "TType.h"
using namespace TTypes;

/**
 * ////////////////////////////////////////////Automat////////////////////////////////////////
 */
Automat::Automat() {
	this->setCurrentState(State0::getInstance());
}

Automat::~Automat() {
}

void Automat::setCurrentState(IState* state) {
	this->mCurrentState = state;
}

void Automat::readChar(char c) {
	this->mCurrentState->read(this, c);
}

void Automat::makeToken(TTypes::TType tokenType)
{
//TODO makeToken
}

/**
 * ////////////////////////////////////////////STATES////////////////////////////////////////
 * State0
 */
State0* State0::instance = 0;
State0* State0::getInstance() {
	if (State0::instance == 0) {
		State0::instance = new State0();
	}
	return State0::instance;
}
void State0::read(Automat* automat, char c) {
	std::cout << "State0 received " << c << std::endl;
	switch (c) {
	case ' ':
		break;
	case '\0':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(UNKNOWN);
		break;
	case '\n':
		automat->setCurrentState(State0::getInstance());
		break;
	case '\r':
		automat->setCurrentState(State0::getInstance());
		break;
	case '/':
		break;
	case '<':
		break;
	case '+':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(PLUS);
		break;
	case '-':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(MINUS);
		break;
	case '*':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(ASTERISK);
		break;
	case '>':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(R_BRACKET);
		break;
	case '=':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(EQUALS);
		break;
	case '!':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(EXCLAMATIONMARK);
		break;
	case '&':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(AMPERSAND);
		break;
	case ';':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(SEMICOLON);
		break;
	case '(':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(L_PARENTHESIS);
		break;
	case ')':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(R_PARENTHESIS);
		break;
	case '{':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(L_BRACE);
		break;
	case '}':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(R_BRACE);
		break;
	case '[':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(L_SQUAREBRACE);
		break;
	case ']':
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(R_SQUAREBRACE);
		break;
	default:
		automat->setCurrentState(State0::getInstance());
		automat->makeToken(UNKNOWN);
	}
}

/**
 * State1
 */
State1* State1::instance = 0;
State1* State1::getInstance() {
	if (State1::instance == 0) {
		State1::instance = new State1();
	}
	return State1::instance;
}
void State1::read(Automat* automat, char c) {
	std::cout << "State1 received " << c << std::endl;
	switch (c) {
	case ' ':
		//do something
		automat->setCurrentState(State2::getInstance());
		break;
	default:
		//do something
		break;
	}
}

/**
 * State2
 */
State2* State2::instance = 0;
State2* State2::getInstance() {
	if (State2::instance == 0) {
		State2::instance = new State2();
	}
	return State2::instance;
}
void State2::read(Automat* automat, char c) {
	std::cout << "State2 received " << c << std::endl;
	switch (c) {
	case ' ':
		//do something
		automat->setCurrentState(State3::getInstance());
		break;
	default:
		//do something
		break;
	}
}

/**
 * State3
 */
State3* State3::instance = 0;
State3* State3::getInstance() {
	if (State3::instance == 0) {
		State3::instance = new State3();
	}
	return State3::instance;
}
void State3::read(Automat* automat, char c) {
	std::cout << "State3 received " << c << std::endl;
	switch (c) {
	case ' ':
		//do something
		automat->setCurrentState(State0::getInstance());
		break;
	default:
		//do something
		break;
	}
}
